// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: GPL-3.0-only

package watch_api_impl

import (
	"context"
	"strings"
	"time"

	"gitcode.com/openseaotter/so_proto_gen_go.git/watch_api"
	"gitcode.com/openseaotter/so_server/config"
	"gitcode.com/openseaotter/so_server/storage"
	"github.com/dchest/uniuri"
	"github.com/google/uuid"
)

type WatchApiImpl struct {
	watch_api.UnimplementedWatchApiServer
}

func (apiImpl *WatchApiImpl) Create(ctx context.Context, req *watch_api.CreateRequest) (*watch_api.CreateResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.CreateResponse{
				Code:   watch_api.CreateResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.CreateResponse{
				Code:   watch_api.CreateResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.CreateResponse{
				Code:   watch_api.CreateResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	fullImageNameList, err := apiImpl.adjustFullImageNameList(ctx, req.FullImageNameList)
	if err != nil {
		return nil, err
	}
	watchId := uuid.NewString()
	secret := uniuri.NewLenChars(32, []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))
	nowTime := time.Now().UnixMilli()

	newInfo := &watch_api.WatchInfo{
		WatchId:           watchId,
		Secret:            secret,
		FullImageNameList: fullImageNameList,
		Desc:              req.Desc,
		ChangeCount:       0,
		CreateTime:        nowTime,
		UpdateTime:        nowTime,
	}

	err = storage.WatchInfoDao.Insert(ctx, newInfo)
	if err != nil {
		return nil, err
	}

	return &watch_api.CreateResponse{
		Code:    watch_api.CreateResponse_CODE_OK,
		WatchId: watchId,
	}, nil
}

func (apiImpl *WatchApiImpl) adjustFullImageNameList(ctx context.Context, fullImageNameList []string) ([]string, error) {
	retList := []string{}
	for _, fullImangeName := range fullImageNameList {
		parts := strings.Split(fullImangeName, "/")
		if len(parts) != 2 {
			continue
		}
		exist, err := storage.ImageInfoDao.Exist(ctx, parts[0], parts[1])
		if err != nil {
			return nil, err
		}
		if exist {
			retList = append(retList, fullImangeName)
		}
	}
	return retList, nil
}

func (apiImpl *WatchApiImpl) List(ctx context.Context, req *watch_api.ListRequest) (*watch_api.ListResponse, error) {
	emptyList := []*watch_api.WatchInfo{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.ListResponse{
				Code:     watch_api.ListResponse_CODE_NO_REMOTE,
				ErrMsg:   "鉴权服务器不存在",
				InfoList: emptyList,
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.ListResponse{
				Code:     watch_api.ListResponse_CODE_NO_PERMISSION,
				ErrMsg:   "没有权限",
				InfoList: emptyList,
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.ListResponse{
				Code:     watch_api.ListResponse_CODE_NO_PERMISSION,
				ErrMsg:   "没有权限",
				InfoList: emptyList,
			}, nil
		}
	}

	watchItemList, err := storage.WatchInfoDao.List(ctx)
	if err != nil {
		return nil, err
	}
	count := len(watchItemList)
	start := int(req.Offset)
	if start >= count {
		return &watch_api.ListResponse{
			Code:       watch_api.ListResponse_CODE_OK,
			TotalCount: uint32(count),
			InfoList:   emptyList,
		}, nil
	}
	end := start + int(req.Limit)
	if end > count {
		end = count
	}

	return &watch_api.ListResponse{
		Code:       watch_api.ListResponse_CODE_OK,
		TotalCount: uint32(count),
		InfoList:   watchItemList[start:end],
	}, nil
}

func (apiImpl *WatchApiImpl) Get(ctx context.Context, req *watch_api.GetRequest) (*watch_api.GetResponse, error) {
	emptyInfo := &watch_api.WatchInfo{
		FullImageNameList: []string{},
	}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.GetResponse{
				Code:   watch_api.GetResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
				Info:   emptyInfo,
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.GetResponse{
				Code:   watch_api.GetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
				Info:   emptyInfo,
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.GetResponse{
				Code:   watch_api.GetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
				Info:   emptyInfo,
			}, nil
		}
	}

	watchItem, err := storage.WatchInfoDao.Get(ctx, req.WatchId)
	if err != nil {
		return &watch_api.GetResponse{
			Code:   watch_api.GetResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
			Info:   emptyInfo,
		}, nil
	}

	return &watch_api.GetResponse{
		Code: watch_api.GetResponse_CODE_OK,
		Info: watchItem,
	}, nil
}

func (apiImpl *WatchApiImpl) Remove(ctx context.Context, req *watch_api.RemoveRequest) (*watch_api.RemoveResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.RemoveResponse{
				Code:   watch_api.RemoveResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.RemoveResponse{
				Code:   watch_api.RemoveResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.RemoveResponse{
				Code:   watch_api.RemoveResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	exist, err := storage.WatchInfoDao.Exist(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &watch_api.RemoveResponse{
			Code: watch_api.RemoveResponse_CODE_OK,
		}, nil
	}

	err = storage.WatchInfoDao.Remove(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}

	err = storage.ChangeDao.RemoveByWatch(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}

	return &watch_api.RemoveResponse{
		Code: watch_api.RemoveResponse_CODE_OK,
	}, nil
}

func (apiImpl *WatchApiImpl) ResetSecret(ctx context.Context, req *watch_api.ResetSecretRequest) (*watch_api.ResetSecretResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.ResetSecretResponse{
				Code:   watch_api.ResetSecretResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.ResetSecretResponse{
				Code:   watch_api.ResetSecretResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.ResetSecretResponse{
				Code:   watch_api.ResetSecretResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	watchItem, err := storage.WatchInfoDao.Get(ctx, req.WatchId)
	if err != nil {
		return &watch_api.ResetSecretResponse{
			Code:   watch_api.ResetSecretResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
		}, nil
	}
	watchItem.Secret = uniuri.NewLenChars(32, []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))
	watchItem.UpdateTime = time.Now().UnixMilli()

	err = storage.WatchInfoDao.Update(ctx, watchItem)
	if err != nil {
		return nil, err
	}

	return &watch_api.ResetSecretResponse{
		Code:   watch_api.ResetSecretResponse_CODE_OK,
		Secret: watchItem.Secret,
	}, nil
}

func (apiImpl *WatchApiImpl) Update(ctx context.Context, req *watch_api.UpdateRequest) (*watch_api.UpdateResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.UpdateResponse{
				Code:   watch_api.UpdateResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.UpdateResponse{
				Code:   watch_api.UpdateResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.UpdateResponse{
				Code:   watch_api.UpdateResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	watchItem, err := storage.WatchInfoDao.Get(ctx, req.WatchId)
	if err != nil {
		return &watch_api.UpdateResponse{
			Code:   watch_api.UpdateResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
		}, nil
	}

	fullImageNameList, err := apiImpl.adjustFullImageNameList(ctx, req.FullImageNameList)
	if err != nil {
		return nil, err
	}

	watchItem.FullImageNameList = fullImageNameList
	watchItem.Desc = req.Desc
	watchItem.UpdateTime = time.Now().UnixMilli()

	err = storage.WatchInfoDao.Update(ctx, watchItem)
	if err != nil {
		return nil, err
	}

	return &watch_api.UpdateResponse{
		Code: watch_api.UpdateResponse_CODE_OK,
	}, nil
}

func (apiImpl *WatchApiImpl) Enable(ctx context.Context, req *watch_api.EnableRequest) (*watch_api.EnableResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.EnableResponse{
				Code:   watch_api.EnableResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.EnableResponse{
				Code:   watch_api.EnableResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.EnableResponse{
				Code:   watch_api.EnableResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	watchItem, err := storage.WatchInfoDao.Get(ctx, req.WatchId)
	if err != nil {
		return &watch_api.EnableResponse{
			Code:   watch_api.EnableResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
		}, nil
	}
	if watchItem.Enable {
		return &watch_api.EnableResponse{
			Code: watch_api.EnableResponse_CODE_OK,
		}, nil
	}

	watchItem.Enable = true
	err = storage.WatchInfoDao.Update(ctx, watchItem)
	if err != nil {
		return nil, err
	}
	return &watch_api.EnableResponse{
		Code: watch_api.EnableResponse_CODE_OK,
	}, nil
}

func (apiImpl *WatchApiImpl) Disable(ctx context.Context, req *watch_api.DisableRequest) (*watch_api.DisableResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.DisableResponse{
				Code:   watch_api.DisableResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.DisableResponse{
				Code:   watch_api.DisableResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.DisableResponse{
				Code:   watch_api.DisableResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	watchItem, err := storage.WatchInfoDao.Get(ctx, req.WatchId)
	if err != nil {
		return &watch_api.DisableResponse{
			Code:   watch_api.DisableResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
		}, nil
	}
	if !watchItem.Enable {
		return &watch_api.DisableResponse{
			Code: watch_api.DisableResponse_CODE_OK,
		}, nil
	}

	watchItem.Enable = false
	err = storage.WatchInfoDao.Update(ctx, watchItem)
	if err != nil {
		return nil, err
	}
	return &watch_api.DisableResponse{
		Code: watch_api.DisableResponse_CODE_OK,
	}, nil
}

func (apiImpl *WatchApiImpl) ListChange(ctx context.Context, req *watch_api.ListChangeRequest) (*watch_api.ListChangeResponse, error) {
	emptyList := []*watch_api.ChangeInfo{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.ListChangeResponse{
				Code:       watch_api.ListChangeResponse_CODE_NO_REMOTE,
				ErrMsg:     "鉴权服务器不存在",
				ChangeList: emptyList,
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.ListChangeResponse{
				Code:       watch_api.ListChangeResponse_CODE_NO_PERMISSION,
				ErrMsg:     "没有权限",
				ChangeList: emptyList,
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.ListChangeResponse{
				Code:       watch_api.ListChangeResponse_CODE_NO_PERMISSION,
				ErrMsg:     "没有权限",
				ChangeList: emptyList,
			}, nil
		}
	}

	exist, err := storage.WatchInfoDao.Exist(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &watch_api.ListChangeResponse{
			Code:       watch_api.ListChangeResponse_CODE_NO_WATCH,
			ErrMsg:     "变更通知配置不存在",
			ChangeList: emptyList,
		}, nil
	}

	changeItemList, err := storage.ChangeDao.List(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}

	count := len(changeItemList)

	if req.Offset >= uint32(count) {
		return &watch_api.ListChangeResponse{
			Code:       watch_api.ListChangeResponse_CODE_OK,
			TotalCount: uint32(count),
			ChangeList: emptyList,
		}, nil
	}
	end := int(req.Offset + req.Limit)

	if end > count {
		end = count
	}

	return &watch_api.ListChangeResponse{
		Code:       watch_api.ListChangeResponse_CODE_OK,
		TotalCount: uint32(count),
		ChangeList: changeItemList[int(req.Offset):end],
	}, nil
}

func (apiImpl *WatchApiImpl) TrigerChange(ctx context.Context, req *watch_api.TrigerChangeRequest) (*watch_api.TrigerChangeResponse, error) {
	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &watch_api.TrigerChangeResponse{
				Code:   watch_api.TrigerChangeResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
			}, nil
		}
		_, localMember, err := storage.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &watch_api.TrigerChangeResponse{
				Code:   watch_api.TrigerChangeResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}

		if !localMember.Perm.ManageWatch {
			return &watch_api.TrigerChangeResponse{
				Code:   watch_api.TrigerChangeResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}

	exist, err := storage.WatchInfoDao.Exist(ctx, req.WatchId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &watch_api.TrigerChangeResponse{
			Code:   watch_api.TrigerChangeResponse_CODE_NO_WATCH,
			ErrMsg: "变更通知配置不存在",
		}, nil
	}

	_, err = storage.ChangeDao.Get(ctx, req.WatchId, req.ChangeId)
	if err != nil {
		return &watch_api.TrigerChangeResponse{
			Code:   watch_api.TrigerChangeResponse_CODE_NO_CHANGE,
			ErrMsg: "变更记录不存在",
		}, nil
	}
	callId := uuid.NewString()
	storage.ChangeNoticeDao.SendChange(req.WatchId, req.ChangeId, callId)

	return &watch_api.TrigerChangeResponse{
		Code: watch_api.TrigerChangeResponse_CODE_OK,
	}, nil
}
